/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambkit.module.upms.server.service.impl;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.jfinal.kit.StrKit;
import com.lambkit.Lambkit;
import com.lambkit.common.service.LambkitService;
import com.lambkit.common.util.StringUtils;
import com.lambkit.component.shiro.processer.*;
import com.lambkit.db.sql.IQuery;
import com.lambkit.db.sql.column.Example;
import com.lambkit.module.upms.model.UpmsLogModel;
import com.lambkit.module.upms.model.UpmsOrganizationModel;
import com.lambkit.module.upms.model.UpmsPermissionModel;
import com.lambkit.module.upms.model.UpmsRoleModel;
import com.lambkit.module.upms.model.UpmsRolePermissionModel;
import com.lambkit.module.upms.model.UpmsSystemModel;
import com.lambkit.module.upms.model.UpmsUserModel;
import com.lambkit.module.upms.model.UpmsUserPermissionModel;
import com.lambkit.module.upms.model.UpmsUserRoleModel;
import com.lambkit.module.upms.sql.UpmsRolePermissionSqlBuilder;
import com.lambkit.module.upms.sql.UpmsUserPermissionSqlBuilder;
import com.lambkit.module.upms.sql.UpmsUserSqlBuilder;
import com.lambkit.module.upms.server.service.*;
import org.apache.shiro.authz.annotation.*;
import com.lambkit.common.service.Service;

import java.lang.annotation.Annotation;
import java.util.List;

/**
 * UpmsApiService实现
 */
@Service
@LambkitService
public class UpmsServerApiServiceImpl implements UpmsServerApiService {

    private static Log _log = LogFactory.get(UpmsServerApiServiceImpl.class);

    UpmsServerApiQuery upmsApiQuery = new UpmsServerApiQuery();//.get(UpmsApiQuery.class);
    
    /**
     * 根据用户id获取所拥有的权限
     * @param upmsUserId
     * @return
     */
    
    public List<UpmsPermissionModel> selectUpmsPermissionByUpmsUserId(Long upmsUserId) {
        // 用户不存在或锁定状态
        UpmsUserModel upmsUser = UpmsUserModel.service().findByPrimaryKey(upmsUserId);
        if (null == upmsUser || 1 == upmsUser.getLocked()) {
            _log.info("selectUpmsPermissionByUpmsUserId : upmsUserId={}", upmsUserId);
            return null;
        }
        List<UpmsPermissionModel> upmsPermissions = upmsApiQuery.selectUpmsPermissionByUpmsUserId(upmsUserId);
        return upmsPermissions;
    }

    /**
     * 根据用户id获取所拥有的权限
     * @param upmsUserId
     * @return
     */
    
    //@Cacheable(value = "zheng-upms-rpc-service-ehcache", key = "'selectUpmsPermissionByUpmsUserId_' + #upmsUserId")
    public List<UpmsPermissionModel> selectUpmsPermissionByUpmsUserIdByCache(Long upmsUserId) {
        return selectUpmsPermissionByUpmsUserId(upmsUserId);
    }

    /**
     * 根据用户id获取所属的角色
     * @param upmsUserId
     * @return
     */
    
    public List<UpmsRoleModel> selectUpmsRoleByUpmsUserId(Long upmsUserId) {
        // 用户不存在或锁定状态
        UpmsUserModel upmsUser = UpmsUserModel.service().findByPrimaryKey(upmsUserId);
        if (null == upmsUser || 1 == upmsUser.getLocked()) {
            _log.info("selectUpmsRoleByUpmsUserId : upmsUserId={}", upmsUserId);
            return null;
        }
        List<UpmsRoleModel> upmsRoles = upmsApiQuery.selectUpmsRoleByUpmsUserId(upmsUserId);
        return upmsRoles;
    }

    /**
     * 根据用户id获取所属的角色
     * @param upmsUserId
     * @return
     */
    
    //@Cacheable(value = "zheng-upms-rpc-service-ehcache", key = "'selectUpmsRoleByUpmsUserId_' + #upmsUserId")
    public List<UpmsRoleModel> selectUpmsRoleByUpmsUserIdByCache(Long upmsUserId) {
        return selectUpmsRoleByUpmsUserId(upmsUserId);
    }

    /**
     * 根据角色id获取所拥有的权限
     * @param upmsRoleId
     * @return
     */
    
    public List<UpmsRolePermissionModel> selectUpmsRolePermisstionByUpmsRoleId(Long upmsRoleId) {
        Example upmsRolePermissionExample = UpmsRolePermissionSqlBuilder.create().andRoleIdEqualTo(upmsRoleId).example();
        List<UpmsRolePermissionModel> upmsRolePermissions = UpmsRolePermissionModel.service().find(upmsRolePermissionExample);
        return upmsRolePermissions;
    }

    /**
     * 根据用户id获取所拥有的权限
     * @param upmsUserId
     * @return
     */
    
    public List<UpmsUserPermissionModel> selectUpmsUserPermissionByUpmsUserId(Long upmsUserId) {
        Example upmsUserPermissionExample = UpmsUserPermissionSqlBuilder.create()
                .andUserIdEqualTo(new Long(upmsUserId)).example();
        List<UpmsUserPermissionModel> upmsUserPermissions = UpmsUserPermissionModel.service().find(upmsUserPermissionExample);
        return upmsUserPermissions;
    }

    /**
     * 根据条件获取系统数据
     * @param
     * @return
     */
    
    public List<UpmsSystemModel> selectUpmsSystemByQuery(IQuery paras) {
        return UpmsSystemModel.service().find(paras);
    }

    
	public List<UpmsSystemModel> selectUpmsSystemByExample(Example upmsSystemExample) {
		// TODO Auto-generated method stub
		return UpmsSystemModel.service().find(upmsSystemExample);
	}

    /**
     * 根据条件获取组织数据
     * @param
     * @return
     */
    
    public List<UpmsOrganizationModel> selectUpmsOrganizationByQuery(IQuery paras) {
        return UpmsOrganizationModel.service().find(paras);
    }
    
    
	public List<UpmsOrganizationModel> selectUpmsOrganizationByExample(Example upmsOrganizationExample) {
		// TODO Auto-generated method stub
		return UpmsOrganizationModel.service().find(upmsOrganizationExample);
	}

    /**
     * 根据username获取UpmsUser
     * @param username
     * @return
     */
    
    public UpmsUserModel selectUpmsUserByUsername(String username) {
    	if(StrKit.isBlank(username)) {
			return null;
		}
        Example upmsUserExample = UpmsUserSqlBuilder.create()
                .andUsernameEqualTo(username).example();
        List<UpmsUserModel> upmsUsers = UpmsUserModel.service().find(upmsUserExample);
        if (null != upmsUsers && upmsUsers.size() > 0) {
            return upmsUsers.get(0);
        }
        return null;
    }
    
    @Override
	public UpmsUserModel selectUpmsUserByEmail(String email) {
		// TODO Auto-generated method stub
    	if(StrKit.isBlank(email)) {
			return null;
		}
    	Example upmsUserExample = UpmsUserSqlBuilder.create()
    			.andEmailEqualTo(email).example();
        List<UpmsUserModel> upmsUsers = UpmsUserModel.service().find(upmsUserExample);
        if (null != upmsUsers && upmsUsers.size() > 0) {
            return upmsUsers.get(0);
        }
        return null;
	}

	@Override
	public UpmsUserModel selectUpmsUserByPhone(String phone) {
		// TODO Auto-generated method stub
		if(StrKit.isBlank(phone)) {
			return null;
		}
		Example upmsUserExample = UpmsUserSqlBuilder.create()
                .andPhoneEqualTo(phone).example();
        List<UpmsUserModel> upmsUsers = UpmsUserModel.service().find(upmsUserExample);
        if (null != upmsUsers && upmsUsers.size() > 0) {
            return upmsUsers.get(0);
        }
        return null;
	}

	@Override
	public UpmsUserModel selectUpmsUserByLoginName(String LoginName) {
		// TODO Auto-generated method stub
		if(StringUtils.isEmail(LoginName)) {
			return selectUpmsUserByEmail(LoginName);
        } else if(StringUtils.isMobileNumber(LoginName)) {
        	return selectUpmsUserByPhone(LoginName);
        } else {
        	return selectUpmsUserByUsername(LoginName);
        }
	}

    @Override
    public UpmsUserModel selectUpmsUserByUserId(Long upmsUserId) {
        return UpmsUserModel.service().findByPrimaryKey(upmsUserId);
    }

    /**
     * 写入操作日志
     * @param record
     * @return
     */
    
    public int insertUpmsLogSelective(UpmsLogModel record) {
        return record.save() ? 1 : -1;
    }

	@Override
	public AuthorizeResult invoke(String target, Annotation[] annotations) {
		// TODO Auto-generated method stub
		if (annotations == null || annotations.length == 0) {
            return AuthorizeResult.ok();
        }
		for (Annotation annotation : annotations) {
			if(Lambkit.isDevMode()) {
				System.out.println("Annotation:" + annotation.annotationType().getName());
			}
			IShiroAuthorizeProcesser processer = null;
			if (annotation.annotationType() == RequiresPermissions.class) {
                processer = new ShiroRequiresPermissionsProcesser((RequiresPermissions) annotation);
            } else if (annotation.annotationType() == RequiresRoles.class) {
                processer = new ShiroRequiresRolesProcesser((RequiresRoles) annotation);
            } else if (annotation.annotationType() == RequiresUser.class) {
            	processer = new ShiroRequiresUserProcesser();
            } else if (annotation.annotationType() == RequiresAuthentication.class) {
            	processer = new ShiroRequiresAuthenticationProcesser();
            } else if (annotation.annotationType() == RequiresGuest.class) {
            	processer = new ShiroRequiresGuestProcesser();
            }
			if (processer != null) {
				AuthorizeResult result = processer.authorize();
				if (result.isFail()) {
	                return result;
	            }
	        }
		}
		return AuthorizeResult.ok();
	}

	@Override
	public List<UpmsOrganizationModel> selectUpmsOrganizationByUpmsUserId(Long upmsUserId) {
		// 用户不存在或锁定状态
        UpmsUserModel upmsUser = UpmsUserModel.service().findByPrimaryKey(upmsUserId);
        if (null == upmsUser || 1 == upmsUser.getLocked()) {
            _log.info("selectUpmsRoleByUpmsUserId : upmsUserId={}", upmsUserId);
            return null;
        }
        List<UpmsOrganizationModel> upmsOrganization = upmsApiQuery.selectUpmsOrganizationByUpmsUserId(upmsUserId);
        return upmsOrganization;
	}

	@Override
	public List<UpmsUserModel> selectUpmsUserByRoleId(Long id) {
		// TODO Auto-generated method stub
		if (null == id) {
            _log.info("selectUpmsUserByRoleId : upmsRoleId={}", id);
            return null;
        }
        List<UpmsUserModel> UpmsUsers = upmsApiQuery.selectUpmsUserByRoleId(id);
        return UpmsUsers;
	}

    @Override
    public UpmsRoleModel selectUpmsRoleByRoleId(Long roleId) {
        return UpmsRoleModel.service().findById(roleId);
    }

    @Override
    public Boolean hasRole(Long userid, Long roleid) {
        return UpmsUserRoleModel.service().hasRole(userid, roleid);
    }

    @Override
    public Boolean hasRole(Long userid, String roleName) {
        return UpmsUserRoleModel.service().hasRole(userid, roleName);
    }

    @Override
    public Boolean lacksRole(String roleName) {
        return UpmsUserRoleModel.service().lacksRole(roleName);
    }

    @Override
    public Boolean hasAnyRoles(Long userid, String roleNames) {
        return UpmsUserRoleModel.service().hasAnyRoles(userid, roleNames);
    }

    @Override
    public Boolean hasAllRoles(Long userid, String roleNames) {
        return UpmsUserRoleModel.service().hasAllRoles(userid, roleNames);
    }

    @Override
    public Boolean hasRule(Long userid, Long ruleid) {
        return UpmsUserPermissionModel.service().hasRule(userid, ruleid);
    }

    @Override
    public Boolean hasRule(Long userid, String permission) {
        return UpmsUserPermissionModel.service().hasRule(userid, permission);
    }

    @Override
    public Boolean lacksRule(String permission) {
        return UpmsUserPermissionModel.service().lacksRule(permission);
    }

    @Override
    public Boolean hasAnyRules(Long userid, String permissions) {
        return UpmsUserPermissionModel.service().hasAnyRules(userid, permissions);
    }

    @Override
    public Boolean hasAllRules(Long userid, String permissions) {
        return UpmsUserPermissionModel.service().hasAllRules(userid, permissions);
    }

}